<?xml version="1.0" encoding="UTF-8" ?>
<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:model="http://euss.evaluant.com/schemas/GenerationModel.xsd">
<xsl:output method="text"/>	

	<xsl:template match="/">
using System;
using System.Reflection;
using System.Collections;
using Evaluant.Uss;
using Evaluant.Uss.ObjectContext;
using Evaluant.Uss.ObjectContext.Descriptors;

#region Custom Usings
#endregion

		<xsl:apply-templates/>
	
	</xsl:template>

	<xsl:template match="model:Package">

namespace <xsl:value-of select="@name"/>
{
	<xsl:apply-templates select="model:Enumeration" mode="declaration"/>
	<xsl:apply-templates select="model:Interface" mode="declaration"/>
	<xsl:apply-templates select="model:Class" mode="declaration"/>
}
</xsl:template>

<!-- Enumerations -->
	
<xsl:template match="model:Enumeration" mode="declaration">
	public enum <![CDATA[ ]]> <xsl:value-of select="@name"/> 
	{ 
		<xsl:apply-templates select="model:Literal" mode="declaration"/>
	}
</xsl:template>

<xsl:template match="model:Literal" mode="declaration">
	<xsl:value-of select="@name"/><xsl:if test="position() != last()">,
		</xsl:if>
</xsl:template>

<xsl:template match="model:Relationship" mode="is-composition">
  <xsl:choose>
    <xsl:when test="@type = 'composition'">true</xsl:when>
    <xsl:otherwise>false</xsl:otherwise>
  </xsl:choose>
</xsl:template>

  <!-- Interfaces -->
<xsl:template match="model:Interface" mode="declaration">
	public interface <xsl:value-of select="@name"/>
	{	
		#region Custom <xsl:value-of select="../@name"/>.<xsl:value-of select="@name"/>
		#endregion

		<xsl:apply-templates select="model:Property" mode="interface-property-declaration" />
	}
</xsl:template>

	<!-- Declares the prototype of every properties of a class with 'get/set' accessors. The return type is the corresponding interface of the return type -->
	<xsl:template match="model:Property" mode="interface-property-declaration">
		<xsl:value-of select="@type"/> <![CDATA[ ]]><xsl:value-of select="@name"/> { get; set; }
		</xsl:template>

	<!-- Declares the prototype of every relationship of a class with 'get' accessor -->
	<xsl:template match="model:Relationship" mode="interface-relationship-declaration-to-many">
		I<xsl:value-of select="model:Child/@name"/>[] <![CDATA[ ]]><xsl:value-of select="model:Child/@role"/> { get; }
</xsl:template>

	<xsl:template match="model:Relationship" mode="interface-relationship-declaration-to-one">
		<xsl:choose>
		<xsl:when test="//model:Enumeration/@name = model:Child/@name">
		<xsl:value-of select="model:Child/@name"/> <![CDATA[ ]]><xsl:value-of select="model:Child/@role"/> { get; set; }
		</xsl:when>
		<xsl:otherwise>
		I<xsl:value-of select="model:Child/@name"/> <![CDATA[ ]]><xsl:value-of select="model:Child/@role"/> { get; }
		</xsl:otherwise>
		</xsl:choose>
</xsl:template>

	<!-- Explicit implementation of the business interface -->
	<xsl:template match="model:Relationship" mode="interface-accessor-to-many">
		I<xsl:value-of select="model:Child/@name"/>[] I<xsl:value-of select="model:Parent/@name"/>.<xsl:value-of select="model:Child/@role"/>
		{	                
			get 
			{ 
				I<xsl:value-of select="model:Child/@name"/>[] result = new I<xsl:value-of select="model:Child/@name"/>[<xsl:value-of select="model:Child/@role"/>.Count];
				<xsl:value-of select="model:Child/@role"/>.CopyTo(result, 0);
				return (I<xsl:value-of select="model:Child/@name"/>[])result; 
			}
		}
	</xsl:template>

	<xsl:template match="model:Relationship" mode="interface-accessor-to-one">
		<xsl:choose>
		<xsl:when test="//model:Enumeration/@name = model:Child/@name" />
		<xsl:otherwise>
		I<xsl:value-of select="model:Child/@name"/> I<xsl:value-of select="model:Parent/@name"/>.<xsl:value-of select="model:Child/@role"/>
		{
			get { return <xsl:value-of select="model:Child/@role"/>; }
		}
		</xsl:otherwise>
		</xsl:choose>
	</xsl:template>

	<!-- Classes-->

<xsl:template match="model:Class" mode="declaration">

	<!-- this variable is used in XPath for finding relashionship of this class -->
	<xsl:variable name="name">
		<xsl:value-of select="@name"/>
	</xsl:variable>

	<!-- the name of the associated business interface -->
	<xsl:variable name="business-interface">I<xsl:value-of select="@name"/></xsl:variable>

	<!-- For each class a specific interface is generated (business interface) -->	
	public interface <xsl:value-of select="$business-interface"/>
	{
		#region Custom <xsl:value-of select="../@name"/>.<xsl:value-of select="$business-interface"/>
		#endregion

		string Id { get; set; }
		<xsl:apply-templates select="model:Property" mode="interface-property-declaration" />
		<xsl:apply-templates select="../model:Relationship[model:Parent/@name = $name and (model:Child/@multiplicity = '*' or model:Child/@multiplicity = '0..*' or model:Child/@multiplicity = '1..*') ]" mode="interface-relationship-declaration-to-many" />
		<xsl:apply-templates select="../model:Relationship[model:Parent/@name = $name and (model:Child/@multiplicity = '1' or model:Child/@multiplicity = '0..1' or model:Child/@multiplicity = '1..1')]" mode="interface-relationship-declaration-to-one" />
	}
	<!-- The interfaces it implements -->
	<xsl:variable name="implement-code"><xsl:if test="@implement">, <xsl:value-of select="@implement"/></xsl:if></xsl:variable>
	<xsl:variable name="implement"><xsl:value-of select="@implement"/></xsl:variable>
	<!-- The classes it derives from -->
	<xsl:variable name="inherit-code"><xsl:if test="@inherit"><xsl:value-of select="@inherit"/>,</xsl:if></xsl:variable>
	
		/// &lt;summary&gt;
	/// &lt;para&gt;
	/// A collection that stores &lt;see cref='<xsl:value-of select="@name"/>'/&gt; objects.
	/// &lt;/para&gt;
	/// &lt;/summary&gt;
	/// &lt;seealso cref='<xsl:value-of select="@name"/>Collection'/&gt;
	[Serializable()]
	public class  <xsl:value-of select="@name"/>Collection : IPersistableCollection 
	{	

		/// &lt;summary&gt;
		/// &lt;para&gt;
		/// Initializes a new instance of &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt;.
		/// &lt;/para&gt;
		/// &lt;/summary&gt;
		public <xsl:value-of select="@name"/>Collection()
		{
		}
		
		/// &lt;summary&gt;
		/// &lt;para&gt;
		/// Initializes a new instance of &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt; based on another &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt;.
		/// &lt;/para&gt;
		/// &lt;/summary&gt;
		/// &lt;param name='val'&gt;
		/// A &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt; from which the contents are copied
		/// &lt;/param&gt;
		public <xsl:value-of select="@name"/>Collection( <xsl:value-of select="@name"/>Collection val)
		{
			this.AddRange(val);	
		}
		
		/// &lt;summary&gt;
		/// &lt;para&gt;
		/// Initializes a new instance of &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt; containing any array of &lt;see cref='<xsl:value-of select="@name"/>'/&gt; objects.
		/// &lt;/para&gt;
		/// &lt;/summary&gt;
		/// &lt;param name='val'&gt;
		/// A array of &lt;see cref='<xsl:value-of select="@name"/>'/&gt; objects with which to intialize the collection
		/// &lt;/param&gt;
		public <xsl:value-of select="@name"/>Collection( <xsl:value-of select="@name"/>[] val)
		{
			this.AddRange(val);
		}
		
		public <xsl:value-of select="@name"/>Collection (ObjectContext persistenceManager, IPersistable parent, string role, IEnumerable data): base(persistenceManager, parent, role, data)
		{
		}
		
		/// &lt;summary&gt;
		/// &lt;para&gt;Represents the entry at the specified index of the &lt;see cref='<xsl:value-of select="@name"/>'/&gt;.&lt;/para&gt;
		/// &lt;/summary&gt;
		/// &lt;param name='index'&gt;&lt;para&gt;The zero-based index of the entry to locate in the collection.&lt;/para&gt;&lt;/param&gt;
		/// &lt;value&gt;
		/// &lt;para&gt; The entry at the specified index of the collection.&lt;/para&gt;
		/// &lt;/value&gt;
		/// &lt;exception cref='System.ArgumentOutOfRangeException'&gt;&lt;paramref name='index'/&gt; is outside the valid range of indexes for the collection.&lt;/exception&gt;
		public new <xsl:value-of select="@name"/> this[int index] 
		{
			get 
			{
				return ((<xsl:value-of select="@name"/>)base[index]);
			}
			set 
			{
				base[index] = value;
			}
		}
		
		/// &lt;summary&gt;
		/// &lt;para&gt;Adds a &lt;see cref='<xsl:value-of select="@name"/>'/&gt; with the specified value to the 
		/// &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt; .&lt;/para&gt;
		/// &lt;/summary&gt;
		/// &lt;param name='val'&gt;The &lt;see cref='<xsl:value-of select="@name"/>'/&gt; to add.&lt;/param&gt;
		/// &lt;returns&gt;
		/// &lt;para&gt;The index at which the new element was inserted.&lt;/para&gt;
		/// &lt;/returns&gt;
		/// &lt;seealso cref='<xsl:value-of select="@name"/>Collection.AddRange'/&gt;
		public int Add( <xsl:value-of select="@name"/> val)
		{
			return base.Add(val);
		}
		
		/// &lt;summary&gt;
		/// &lt;para&gt;
		/// Adds the contents of another &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt; to the end of the collection.
		/// &lt;/para&gt;
		/// &lt;/summary&gt;
		/// &lt;param name='val'&gt;
		/// A &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt; containing the objects to add to the collection.
		/// &lt;/param&gt;
		/// &lt;returns&gt;
		/// &lt;para&gt;None.&lt;/para&gt;
		/// &lt;/returns&gt;
		/// &lt;seealso cref='<xsl:value-of select="@name"/>Collection.Add'/&gt;
		public void AddRange( <xsl:value-of select="@name"/>Collection val)
		{
			base.AddRange(val);
		}
		public void AddRange( <xsl:value-of select="@name"/>[] val)
		{
			base.AddRange(val);
		}
		
		/// &lt;summary&gt;
		/// &lt;para&gt;Gets a value indicating whether the 
		/// &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt; contains the specified &lt;see cref='<xsl:value-of select="@name"/>'/&gt;.&lt;/para&gt;
		/// &lt;/summary&gt;
		/// &lt;param name='val'&gt;The &lt;see cref='<xsl:value-of select="@name"/>'/&gt; to locate.&lt;/param&gt;
		/// &lt;returns&gt;
		/// &lt;para&gt;&lt;see langword='true'/&gt; if the &lt;see cref='<xsl:value-of select="@name"/>'/&gt; is contained in the collection; 
		/// otherwise, &lt;see langword='false'/&gt;.&lt;/para&gt;
		/// &lt;/returns&gt;
		/// &lt;seealso cref='<xsl:value-of select="@name"/>Collection.IndexOf'/&gt;
		public bool Contains( <xsl:value-of select="@name"/> val)
		{
			return base.Contains(val);
		}
		
		/// &lt;summary&gt;
		/// &lt;para&gt;Copies the &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt; values to a one-dimensional &lt;see cref='System.Array'/&gt; instance at the 
		/// specified index.&lt;/para&gt;
		/// &lt;/summary&gt;
		/// &lt;param name='array'&gt;&lt;para&gt;The one-dimensional &lt;see cref='System.Array'/&gt; that is the destination of the values copied from &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt; .&lt;/para&gt;&lt;/param&gt;
		/// &lt;param name='index'&gt;The index in &lt;paramref name='array'/&gt; where copying begins.&lt;/param&gt;
		/// &lt;returns&gt;
		/// &lt;para&gt;None.&lt;/para&gt;
		/// &lt;/returns&gt;
		/// &lt;exception cref='System.ArgumentException'&gt;&lt;para&gt;&lt;paramref name='array'/&gt; is multidimensional.&lt;/para&gt; &lt;para&gt;-or-&lt;/para&gt; &lt;para&gt;The number of elements in the &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt; is greater than the available space between &lt;paramref name='index'/&gt; and the end of &lt;paramref name='array'/&gt;.&lt;/para&gt;&lt;/exception&gt;
		/// &lt;exception cref='System.ArgumentNullException'&gt;&lt;paramref name='array'/&gt; is &lt;see langword='null'/&gt;. &lt;/exception&gt;
		/// &lt;exception cref='System.ArgumentOutOfRangeException'&gt;&lt;paramref name='index'/&gt; is less than &lt;paramref name='array'/&gt;'s lowbound. &lt;/exception&gt;
		/// &lt;seealso cref='System.Array'/&gt;
		public void CopyTo( <xsl:value-of select="@name"/>[] array, int index)
		{
			base.CopyTo(array, index);
		}
		
		/// &lt;summary&gt;
		/// &lt;para&gt;Returns the index of a &lt;see cref='<xsl:value-of select="@name"/>'/&gt; in 
		/// the &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt; .&lt;/para&gt;
		/// &lt;/summary&gt;
		/// &lt;param name='val'&gt;The &lt;see cref='<xsl:value-of select="@name"/>'/&gt; to locate.&lt;/param&gt;
		/// &lt;returns&gt;
		/// &lt;para&gt;The index of the &lt;see cref='<xsl:value-of select="@name"/>'/&gt; of &lt;paramref name='val'/&gt; in the 
		/// &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt;, if found; otherwise, -1.&lt;/para&gt;
		/// &lt;/returns&gt;
		/// &lt;seealso cref='<xsl:value-of select="@name"/>Collection.Contains'/&gt;
		public int IndexOf( <xsl:value-of select="@name"/> val)
		{
			return base.IndexOf(val);
		}
		
		/// &lt;summary&gt;
		/// &lt;para&gt;Inserts a &lt;see cref='<xsl:value-of select="@name"/>'/&gt; into the &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt; at the specified index.&lt;/para&gt;
		/// &lt;/summary&gt;
		/// &lt;param name='index'&gt;The zero-based index where &lt;paramref name='val'/&gt; should be inserted.&lt;/param&gt;
		/// &lt;param name='val'&gt;The &lt;see cref='<xsl:value-of select="@name"/>'/&gt; to insert.&lt;/param&gt;
		/// &lt;returns&gt;&lt;para&gt;None.&lt;/para&gt;&lt;/returns&gt;
		/// &lt;seealso cref='<xsl:value-of select="@name"/>Collection.Add'/&gt;
		public void Insert(int index,  <xsl:value-of select="@name"/> val)
		{
			base.Insert(index, val);
		}
		
		/// &lt;summary&gt;
		/// &lt;para&gt;Returns an enumerator that can iterate through 
		/// the &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt; .&lt;/para&gt;
		/// &lt;/summary&gt;
		/// &lt;returns&gt;&lt;para&gt;None.&lt;/para&gt;&lt;/returns&gt;
		/// &lt;seealso cref='System.Collections.IEnumerator'/&gt;
		public new  <xsl:value-of select="@name"/>Enumerator GetEnumerator()
		{
			return new  <xsl:value-of select="@name"/>Enumerator(this);
		}
		
		/// &lt;summary&gt;
		/// &lt;para&gt; Removes a specific &lt;see cref='<xsl:value-of select="@name"/>'/&gt; from the 
		/// &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt; .&lt;/para&gt;
		/// &lt;/summary&gt;
		/// &lt;param name='val'&gt;The &lt;see cref='<xsl:value-of select="@name"/>'/&gt; to remove from the &lt;see cref='<xsl:value-of select="@name"/>Collection'/&gt; .&lt;/param&gt;
		/// &lt;returns&gt;&lt;para&gt;None.&lt;/para&gt;&lt;/returns&gt;
		/// &lt;exception cref='System.ArgumentException'&gt;&lt;paramref name='val'/&gt; is not found in the Collection. &lt;/exception&gt;
		public void Remove( <xsl:value-of select="@name"/> val)
		{
			base.Remove(val);
		}
		
		public class  <xsl:value-of select="@name"/>Enumerator : IEnumerator
		{
			IEnumerator baseEnumerator;
			IEnumerable temp;
			
			public  <xsl:value-of select="@name"/>Enumerator( <xsl:value-of select="@name"/>Collection mappings)
			{
				this.temp = mappings;
				this.baseEnumerator = temp.GetEnumerator();
			}
			
			public  <xsl:value-of select="@name"/> Current 
			{
				get 
				{
					return (( <xsl:value-of select="@name"/>)(baseEnumerator.Current));
				}
			}
			
			object IEnumerator.Current 
			{
				get 
				{
					return baseEnumerator.Current;
				}
			}
			
			public bool MoveNext()
			{
				return baseEnumerator.MoveNext();
			}
			
			bool IEnumerator.MoveNext()
			{
				return baseEnumerator.MoveNext();
			}
			
			public void Reset()
			{
				baseEnumerator.Reset();
			}
			
			void IEnumerator.Reset()
			{
				baseEnumerator.Reset();
			}
		}
	}

	<xsl:variable name="inherit"><xsl:value-of select="@inherit"/></xsl:variable>
	[Serializable]
	public class <xsl:value-of select="@name"/> : <xsl:value-of select="$inherit-code" /> IPersistable, <xsl:value-of select="$business-interface" /><xsl:value-of select="$implement-code" /> 
	{		
	
		#region Custom Fields for <xsl:value-of select="../@name"/>.<xsl:value-of select="@name"/>
		#endregion
		
	<xsl:if test = "not(@inherit)">
		[NonSerialized]
		protected Entity _Entity;
		
		[NonSerialized]
		protected ObjectContext _PersistenceManager;
		
		Entity IPersistable.Entity
		{
			get
			{
				return _Entity;
			}
			set
			{
				_Entity = value;
			}
		}
		
		ObjectContext IPersistable.ObjectContext
		{
			get
			{
				return _PersistenceManager;
			}
			set
			{
				_PersistenceManager = value;
			}
		}
		
		public string Id
		{
			get
			{
				return _Entity.Id;
			}
			set
			{
				_Entity.Id = value;
			}
		}
		
	</xsl:if>
	<xsl:text>
		void IPersistable.TrackChildren()
		{
			// if the object is not tracked there is nothing to do
			if(_PersistenceManager == null)
				return;
	</xsl:text>
	<xsl:apply-templates select="." mode="trackchildren-implementation" />		
	<xsl:text>
		}
		
	</xsl:text>
	<!-- the code for the inner properties -->
	<xsl:apply-templates select="model:Property" mode="property-implementation" />
	<!-- TODO : manage multiple interface implementation here -->
	<!-- the code for the properties from the implemented interface -->
	<xsl:apply-templates select="//model:Interface[@name = $implement]/model:Property" mode="property-implementation" />
	<!-- Relationships accessors including enumerations -->
	<xsl:apply-templates select="//model:Relationship[(model:Parent/@name = $name) and (model:Child/@multiplicity = '*' or model:Child/@multiplicity = '0..*' or model:Child/@multiplicity = '1..*' )]" mode="relationship-implementation-to-many" />
	<xsl:apply-templates select="//model:Relationship[(model:Parent/@name = $name) and (model:Child/@multiplicity = '1' or model:Child/@multiplicity = '0..1' or model:Child/@multiplicity = '1..1')]" mode="relationship-implementation-to-one" />
	<!-- Relationships accessors for explicit implemenation of business interface -->
	<xsl:apply-templates select="//model:Relationship[(model:Parent/@name = $name) and (model:Child/@multiplicity = '*' or model:Child/@multiplicity = '0..*' or model:Child/@multiplicity = '1..*' )]" mode="interface-accessor-to-many" />
	<xsl:apply-templates select="//model:Relationship[(model:Parent/@name = $name) and (model:Child/@multiplicity = '1' or model:Child/@multiplicity = '0..1' or model:Child/@multiplicity = '1..1')]" mode="interface-accessor-to-one" />
	<!-- Constructors -->
		public <xsl:value-of select="@name"/> ()
		{
			this._Entity = new Entity(ObjectContext.ConvertNamespaceDomainToEuss(this.GetType().FullName));
		}

		public <xsl:value-of select="@name"/> (Entity e)
		{
			this._Entity = e;
		}

		#region Custom Methods for <xsl:value-of select="../@name"/>.<xsl:value-of select="@name"/>
		#endregion

	}
</xsl:template>

	<!-- The code for tracking all related objects. Applied to all inherited classes -->
	<xsl:template match="model:Class" mode="trackchildren-implementation">
		<!-- this variable is used in XPath for finding relashionship of this class -->
		<xsl:variable name="name">
			<xsl:value-of select="@name"/>
		</xsl:variable>
		<xsl:variable name="inherit">
			<xsl:value-of select="@inherit"/>
		</xsl:variable>
		<xsl:apply-templates select="//model:Relationship[model:Parent/@name = $name ]" mode="trackchildren-implementation" />
		<!-- recursive call for adding the implementation to all parent relationships -->
		<xsl:apply-templates select="//model:Class[@name = $inherit]" mode="trackchildren-implementation" />
	</xsl:template>

	<!-- The code for tracking a relationship -->
	<xsl:template match="model:Relationship" mode="trackchildren-implementation">
		<xsl:choose>
		<xsl:when test="//model:Enumeration/@name = model:Child/@name" />
		<xsl:otherwise>
			if(_<xsl:value-of select="model:Child/@role"/> != null)
				_PersistenceManager.TrackObject(_<xsl:value-of select="model:Child/@role"/>);
		</xsl:otherwise>
		</xsl:choose>
	</xsl:template>

	<!-- the implementation of a property to get/set from the Entity -->
	<xsl:template match="model:Property" mode="property-implementation">
		protected <xsl:value-of select="@type"/> _<xsl:value-of select="@name"/>;
		
		public <xsl:value-of select="@type"/> <![CDATA[ ]]> <xsl:value-of select="@name"/>
		{
			get 
			{ 
				if(_Entity != null &amp;&amp; !_Entity.IsNull("<xsl:value-of select="@name"/>"))
					_<xsl:value-of select="@name"/> = (<xsl:value-of select="@type"/>)this._Entity["<xsl:value-of select="@name"/>"]; 
					
				return _<xsl:value-of select="@name"/>;
			}
		
			set 
			{ 
				_<xsl:value-of select="@name"/> = value;
				if(_Entity != null)
					this._Entity["<xsl:value-of select="@name"/>"] = value; 
			}
		}
		<xsl:apply-templates/>	
	</xsl:template>

	<!-- the implementation of a relationship accessors-->
	<xsl:template match="model:Relationship" mode="relationship-implementation-to-many">
		
		protected <xsl:value-of select="model:Child/@name"/>Collection _<xsl:value-of select="model:Child/@role"/>;
    
    [PersistentProperty("_<xsl:value-of select="model:Child/@role"/>", <xsl:apply-templates select="." mode="is-composition" />)]
		public <xsl:value-of select="model:Child/@name"/>Collection <![CDATA[ ]]><xsl:value-of select="model:Child/@role"/>
		{
			get
			{
				if(_<xsl:value-of select="model:Child/@role"/> == null)
				{
					// Inferred relationships
					EntitySet entities = _Entity.GetEntitySet("<xsl:value-of select="model:Child/@role"/>");
					IList items = entities.Count == 0 ? null : _PersistenceManager.LoadWithEntities(entities);

					_<xsl:value-of select="model:Child/@role"/> = new <xsl:value-of select="model:Child/@name"/>Collection(_PersistenceManager, this, "<xsl:value-of select="model:Child/@role"/>", items);
				}
				
				return _<xsl:value-of select="model:Child/@role"/>;
			}	

			set // Defined for Serialized compatibility only
			{
				_<xsl:value-of select="model:Child/@role"/> = value;
			}
		}	
</xsl:template>

	<!-- the implementation of a relationship accessors-->
	<xsl:template match="model:Relationship" mode="relationship-implementation-to-one">
		<xsl:choose>
			<xsl:when test="//model:Enumeration/@name = Child/@name">
		protected <xsl:value-of select="model:Child/@name"/> <![CDATA[ ]]> _<xsl:value-of select="model:Child/@role"/>;

    [PersistentProperty("_<xsl:value-of select="model:Child/@role"/>", <xsl:apply-templates select="." mode="is-composition" />)]
    public <xsl:value-of select="model:Child/@name"/> <![CDATA[ ]]> <xsl:value-of select="model:Child/@role"/>
		{
			get
			{
				if(_Entity != null)
				{
					if(_Entity.IsNull("<xsl:value-of select="model:Child/@role"/>"))
						_<xsl:value-of select="model:Child/@role"/> = (new <xsl:value-of select="model:Child/@name"/>[1])[0];
					else
						_<xsl:value-of select="model:Child/@role"/> = (<xsl:value-of select="model:Child/@name"/>)Enum.Parse(typeof(<xsl:value-of select="model:Child/@name"/>), (string)this._Entity["<xsl:value-of select="model:Child/@role" />"]);
				}
				
				return _<xsl:value-of select="model:Child/@role"/>;
			}
		
			set 
			{ 
				_<xsl:value-of select="model:Child/@role"/> = value;
				if(_Entity != null)
					this._Entity["<xsl:value-of select="model:Child/@role" />"] = Enum.GetName(typeof(<xsl:value-of select="model:Child/@name"/>), value);
			}
		}
			</xsl:when>
			<xsl:otherwise>
		[NonSerialized]
		private bool _Is<xsl:value-of select="model:Child/@role"/>Loaded = false;

		protected <xsl:value-of select="model:Child/@name"/> _<xsl:value-of select="model:Child/@role"/>;

		public <xsl:value-of select="model:Child/@name"/> <![CDATA[ ]]><xsl:value-of select="model:Child/@role"/>
		{
			get 
			{ 
				if(!_Is<xsl:value-of select="model:Child/@role"/>Loaded &amp;&amp; _PersistenceManager != null &amp;&amp; _Entity != null)
				{
					// Inferred relationships
                    Entity entity = _Entity.GetEntity("<xsl:value-of select="model:Child/@role"/>");
                    IList items = null;
                    if(entity == null)
                    {
                        if(_Entity.InferredReferences.Contains("<xsl:value-of select="model:Child/@role"/>"))
                            _<xsl:value-of select="model:Child/@role"/> = null;
                        else
                            items = _PersistenceManager.LoadReference(_Entity, "<xsl:value-of select="model:Child/@role"/>");
                    }
                    else
                    {
                        items = _PersistenceManager.LoadWithEntities(new EntitySet( new Entity[] { entity }));
                    }

					if(items != null &amp;&amp; items.Count > 0)
						_<xsl:value-of select="model:Child/@role"/> = (<xsl:value-of select="model:Child/@name"/>)items[0];
				}
				
				_Is<xsl:value-of select="model:Child/@role"/>Loaded = true;
				return _<xsl:value-of select="model:Child/@role"/>;
			}
			set
			{
				// Removes the reference to an existing entity
				if(<xsl:value-of select="model:Child/@role"/> != null &amp;&amp; _Entity != null)
				{
					_Entity.DeleteElement("<xsl:value-of select="model:Child/@role"/>");
				}
				
				// Creates the reference only if it is a concrete entity
				if(value != null &amp;&amp; _Entity != null)
				{
					_Entity.AddValue("<xsl:value-of select="model:Child/@role"/>", ((IPersistable)value).Entity);
				}
				_<xsl:value-of select="model:Child/@role"/> = value;
			}
		}				
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>

</stylesheet>

  
